//
//  StringFormatTests.swift
//  UtilityTests
//
//  Created by yuhus on 2023/10/25.
//

import Foundation
import Nimble
import XCTest

final class StringFormatTests: XCTestCase {
  
  func testPrefixAndCountCN() throws {
    // 单词首字母大写，其余小写
    expect("试试长度".prefixAndCountCN(4)).to(equal(("试试", 4)))
    expect("试试长度".prefixAndCountCN(7)).to(equal(("试试长",  6)))
    expect("1试试长度".prefixAndCountCN(7)).to(equal(("1试试长",  7)))
    expect("1试试长度".prefixAndCountCN(8)).to(equal(("1试试长",  7)))
    expect("试试长1度".prefixAndCountCN(7)).to(equal(("试试长1",  7)))
  }
  
  func testString() throws {
    // 单词首字母大写，其余小写
    expect("This property performs".capitalized).to(equal("This Property Performs"))
    expect("This.property_performs".capitalized).to(equal("This.Property_Performs"))
    expect("Thisproperty_performs".capitalized).to(equal("Thisproperty_Performs"))
    expect("ThIs property pERforms".capitalized).to(equal("This Property Performs"))
    
    // Number 格式化
    expect(String.formatted(567)).to(equal("567"))
    expect(String.formatted(1000)).to(equal("1.0K"))
    expect(String.formatted(1000_000)).to(equal("1000.0K"))
    expect(String.formatted(2178)).to(equal("2.2K"))
    
    if #available(iOS 15.0, *) {
      expect(1000_000.formatted()).to(equal("1,000,000"))
    }
  }
  
  func testVersionCode() throws {
    expect("1.2.4".versionCode).to(equal(10204))
    expect("1.01.23".versionCode).to(equal(10123))
    expect("123.45.67".versionCode).to(equal(1234567))
    expect("12.345.67".versionCode).to(equal(1234567))
    expect("12.34.567".versionCode).to(equal(1234567))
  }
  
  /// 字符串格式说明符，还可以使用“n$”位置说明符，例如 %1$@ %2$s。
  /// - [Format Specifiers]( https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html#//apple_ref/doc/uid/TP40004265-SW1)
  func testFormatSpecifiers() throws {
    // [%@] Objective-C 对象，打印可用的 descriptionWithLocale 字符串：否则打印 description。 也适用于 CFTypeRef 对象，返回 CFCopyDescription 函数的结果。
    expect(String(format: "%@ 是男神", "刘德华")).to(equal("刘德华 是男神"))
    
    // [%s] 以 Null 结尾的 8 位无符号字符数组。 由于 %s 说明符会导致以系统默认编码解释字符，因此结果可能会发生变化，尤其是对于从右到左的语言。 例如，对于 RTL，当字符的方向性不强时，%s 会插入方向标记。 因此，最好避免使用 %s 并显式指定编码。
    print(String(format: "%s 是男神", "刘德华")) // XÏ˚˜ 是男神
    
    // 【%d, %D】有符号 32 位整数 (int)。
    expect(String(format: "有 %4d 个专辑", 10)).to(equal("有   10 个专辑"))
    expect(String(format: "有 %04d 个专辑", 10)).to(equal("有 0010 个专辑"))
    expect(String(format: "有 %4D 个专辑", 10)).to(equal("有   10 个专辑"))
    expect(String(format: "有 %04D 个专辑", 10)).to(equal("有 0010 个专辑"))
    
    // [%f] 64 位浮点数（双精度）。
    // [%F] 64 位浮点数（双精度），以十进制表示法打印。
    expect(String(format: "有 %f 亿个粉丝", 1.1111)).to(equal("有 1.111100 亿个粉丝"))
    expect(String(format: "有 %.0f 亿个粉丝", 1.1111)).to(equal("有 1 亿个粉丝"))
    expect(String(format: "有 %.2f 亿个粉丝", 1.1456)).to(equal("有 1.15 亿个粉丝"))
    expect(String(format: "有 %.2f 亿个粉丝", 1.1543)).to(equal("有 1.15 亿个粉丝"))
    
    // [%e] 64 位浮点数（双精度），以科学计数法打印，使用小写 e 引入指数。
    // [%E] 64 位浮点数（双精度），以科学记数法打印，使用大写 E 来引入指数。
    
    expect(String(format: "有 %e 亿个粉丝", 3.14159265359)).to(equal("有 3.141593e+00 亿个粉丝"))
    expect(String(format: "有 %E 亿个粉丝", 3.14159265359)).to(equal("有 3.141593E+00 亿个粉丝"))
    expect(String(format: "有 %.1e 亿个粉丝", 3.14)).to(equal("有 3.1e+00 亿个粉丝"))
    expect(String(format: "有 %.2E 亿个粉丝", 3.14)).to(equal("有 3.14E+00 亿个粉丝"))
    
    // [%g] 64 位浮点数（双精度），如果指数小于 –4 或大于或等于精度，则以 %e 样式打印，否则以 %f 样式打印。
    // [%G] 64 位浮点数（双精度），如果指数小于 –4 或大于或等于精度，则以 %E 样式打印，否则以 %f 样式打印。
    expect(String(format: "有 %g 亿个粉丝", 3.14159265359)).to(equal("有 3.14159 亿个粉丝"))
    expect(String(format: "有 %G 亿个粉丝", 3.14159265359)).to(equal("有 3.14159 亿个粉丝"))
    expect(String(format: "有 %.1g 亿个粉丝", 3.14)).to(equal("有 3 亿个粉丝"))
    expect(String(format: "有 %.1G 亿个粉丝", 3.14)).to(equal("有 3 亿个粉丝"))
    expect(String(format: "有 %.2g 亿个粉丝", 3.14)).to(equal("有 3.1 亿个粉丝"))
    expect(String(format: "有 %.2G 亿个粉丝", 3.14)).to(equal("有 3.1 亿个粉丝"))
  }
}
